/**
 * com.chaeron.GPS - An API for access to GPS devices.
 *
 *
 * Copyright (c) 2001, 2002 Chaeron Corporation,
 * All rights reserved.
 * 
 * Chaeron grants you a non-exclusive license to use, modify and re-distribute
 * this program under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version, provided that this copyright notice and 
 * license appear on all copies of the software.
 * 
 * Software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR
 * IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
 * HEREBY EXCLUDED. THE ENTIRE RISK ARISING OUT OF USING THE SOFTWARE IS ASSUMED
 * BY THE LICENSEE. See the GNU General Public License for more details.
 *
 * CHAERON AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
 * LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR DISTRIBUTING SOFTWARE.
 * IN NO EVENT WILL CHAERON OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
 * PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL
 * OR PUNITIVE DAMAGES, HOWEVER CAUSED AN REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF CHAERON HAS
 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 * @version     1.02
 * @author      Andrzej Jan Taramina, Chaeron Corporation
 *              andrzej@chaeron.com
 */

package com.chaeron.GPS.Garmin;

//***************************************************************************
//*
//*     Imports
//*
//***************************************************************************/

import com.chaeron.GPS.*;
import com.chaeron.GPS.event.*;
import com.chaeron.GPS.exception.*;


//***************************************************************************
//*
//*     RouteHeaderGarminPacket Class definition
//*
//***************************************************************************/

/**
 * The RouteHeaderGarminPacket class represents Waypoint Data Packets
 *
 */

public class RouteHeaderGarminPacket extends GarminPacket
{
	//***************************************************************************
	//*
	//*     Constant definitions
	//*
	//***************************************************************************/
	
	//***************************************************************************
	//*
	//*     Attributes
	//*
	//***************************************************************************/
	
	private Protocol	protocol					= null;
	
	private byte		number						= 0x00;			// Route Number
	private String		identification				= "";
	private String		comment						= "";
	
	
	//***************************************************************************
	//*
	//*     Constructors
	//*
	//***************************************************************************/
	
	/**
	 * Create a RouteHeaderGarminPacket from the given packet data
	 *
	 * @param	protocol	current protocol
	 * @param	packet		packet data buffer
	 * @param	len			length of packet data
	 */
	
	RouteHeaderGarminPacket( Protocol protocol, byte[] packet, int len )
	{  
		super( packet, len );
		
		this.protocol = protocol;
	}
	
	
	//***************************************************************************
	//*
	//*     decode method
	//*
	//***************************************************************************/
	
	/**
	 * Decode the data fields.
	 *
	 * @throws GPSPacketException
	 * @throws GPSFunctionUnavailableException
	 */
	
	public void parseData() throws GPSPacketException, GPSFunctionUnavailableException, GPSWaypointException
	{
		switch( protocol.getDataProtocol( Protocol.APP_PROTOCOL_ROUTE_XFER, Protocol.DATA_PROTOCOL_1 ) ) {
				
			case Protocol.DATA_PROTOCOL_UNDEFINED:
				throw( new GPSWaypointException( GPSRouteException.EXCEPTION_INVALID_ROUTE_HEADER_TYPE ) );
				
			case Protocol.DATA_PROTOCOL_D200:
				parseDataD200();
				break;
				
			case Protocol.DATA_PROTOCOL_D201:
				parseDataD201();
				break;
				
			case Protocol.DATA_PROTOCOL_D202:
				parseDataD202();
				break;
				
			default:
				throw( new GPSWaypointException( GPSRouteException.EXCEPTION_UNSUPPORTED_ROUTE_HEADER_TYPE ) );
		}	
	}
	
	
	/**
	 * Decode the data fields for a D200 Route Header Protocol
	 *
	 * @throws GPSPacketException
	 * @throws GPSFunctionUnavailableException
	 */
	
	public void parseDataD200() throws GPSPacketException, GPSFunctionUnavailableException
	{  
		if( getPacketIDByte() != protocol.getProtocolPacketID( Protocol.GARMIN_PID_ROUTE_HDR ) ) {
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETID_INVALID ) );
		} else if( getDataLength() < 1 ) {  					// Min Packet length For D200 only!!!
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETLENGTH_INVALID ) );
		} else {
			number						= getDataByte( 0 );
		}
	}
	
	
	/**
	 * Decode the data fields for a D201 Route Header Protocol
	 *
	 * @throws GPSPacketException
	 * @throws GPSFunctionUnavailableException
	 */
	
	public void parseDataD201() throws GPSPacketException, GPSFunctionUnavailableException
	{  
		if( getPacketIDByte() != protocol.getProtocolPacketID( Protocol.GARMIN_PID_ROUTE_HDR ) ) {
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETID_INVALID ) );
		} else if( getDataLength() < 21 ) {  					// Min Packet length For D201 only!!!
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETLENGTH_INVALID ) );
		} else {
			byte[]	cmt					= new byte[ 20 ];
			
			number						= getDataByte( 0 );
			
			cmt							= getDataBytes( 1, 20 );
			comment						= new String( cmt );
			
		}
	}
	
	
	/**
	 * Decode the data fields for a D202 Route Header Protocol
	 *
	 * @throws GPSPacketException
	 * @throws GPSFunctionUnavailableException
	 */
	
	public void parseDataD202() throws GPSPacketException, GPSFunctionUnavailableException
	{  
		if( getPacketIDByte() != protocol.getProtocolPacketID( Protocol.GARMIN_PID_ROUTE_HDR ) ) {
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETID_INVALID ) );
		} else if( getDataLength() < 1 ) {  					// Min Packet length For D102 only!!!
			throw( new GPSPacketException( GPSPacketException.EXCEPTION_PACKETLENGTH_INVALID ) );
		} else {
			identification				= getGarminString( 0 );
		}
	}
	
	
	//***************************************************************************
	//*
	//*     Packet Processing Methods
	//*
	//***************************************************************************/
	
	/**
	 * Process the packet
	 *
	 * @param	gps			the GPS object that requested the packet to be processed
	 */
	
	void process( GPS gps )
	{
		if( !isParsed() ) {
			try {
				parse();
				gps.postGPSEvent( new GPSEvent( GPSEvent.GPS_EVENT_ROUTE_HEADER, this ) );
			}
			catch( GPSException exception ) {
				gps.postGPSEvent( new GPSEvent( GPSEvent.GPS_EVENT_ERROR, toString(), exception ) );
			}
		}
	}
	
	
	/**
	 * Get events generated.
	 *
	 * @return		return a valid event type(s) that will be generated by this packet
	 */
	
	static int getEventsGenerated()
	{  
		return( GPSEvent.GPS_EVENT_ERROR | GPSEvent.GPS_EVENT_ROUTE_HEADER );
	}
	
	
	//***************************************************************************
	//*
	//*    Accessor methods
	//*
	//***************************************************************************/
	
	/**
	 * Get the Route Number
	 *
	 * @return		Route Number
	 */
	
	public byte getNumber()
	{  
		return( number );
	}
	
	
	/**
	 * Get the Identification String
	 *
	 * @return		Identification String
	 */
	
	public String getIdentification()
	{  
		return( identification );
	}
	
	
	/**
	 * Get the Comment String
	 *
	 * @return		Comment String
	 */
	
	public String getComment()
	{  
		return( comment );
	}
	
}
